// STUNProtocol.h: interface for the CTurnMessage class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_STUNPROTOCOL_H__70690076_F20A_4DA5_B0E5_FB14D1F22751__INCLUDED_)
#define AFX_STUNPROTOCOL_H__70690076_F20A_4DA5_B0E5_FB14D1F22751__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "Attribute.h"
#include <string.h>
//****************** RFC3489 *************************
///
//					rfc3489
//
//****************************************************

/*
   Message Header

   All STUN messages consist of a 20 byte header:

    0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |      STUN Message Type        |         Message Length        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                            Transaction ID
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                                                   |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

   The Message Types can take on the following values:

      0x0001  :  Binding Request
      0x0101  :  Binding Response
      0x0111  :  Binding Error Response
      0x0002  :  Shared Secret Request
      0x0102  :  Shared Secret Response
      0x0112  :  Shared Secret Error Response

   The message length is the count, in bytes, of the size of the
   message, not including the 20 byte header.

   The transaction ID is a 128 bit identifier.  It also serves as salt
   to randomize the request and the response.  All responses carry the
   same identifier as the request they correspond to.

  Message Attributes
   0x0001: MAPPED-ADDRESS
   0x0002: RESPONSE-ADDRESS
   0x0003: CHANGE-REQUEST
   0x0004: SOURCE-ADDRESS
   0x0005: CHANGED-ADDRESS
   0x0006: USERNAME
   0x0007: PASSWORD
   0x0008: MESSAGE-INTEGRITY
   0x0009: ERROR-CODE
   0x000a: UNKNOWN-ATTRIBUTES
   0x000b: REFLECTED-FROM


 
                                         Binding  Shared  Shared  Shared
                       Binding  Binding  Error    Secret  Secret  Secret
   Att.                Req.     Resp.    Resp.    Req.    Resp.   Error
                                                                  Resp.
   _____________________________________________________________________
   MAPPED-ADDRESS      N/A      M        N/A      N/A     N/A     N/A
   RESPONSE-ADDRESS    O        N/A      N/A      N/A     N/A     N/A
   CHANGE-REQUEST      O        N/A      N/A      N/A     N/A     N/A
   SOURCE-ADDRESS      N/A      M        N/A      N/A     N/A     N/A
   CHANGED-ADDRESS     N/A      M        N/A      N/A     N/A     N/A
   USERNAME            O        N/A      N/A      N/A     M       N/A
   PASSWORD            N/A      N/A      N/A      N/A     M       N/A
   MESSAGE-INTEGRITY   O        O        N/A      N/A     N/A     N/A
   ERROR-CODE          N/A      N/A      M        N/A     N/A     M
   UNKNOWN-ATTRIBUTES  N/A      N/A      C        N/A     N/A     C
   REFLECTED-FROM      N/A      C        N/A      N/A     N/A     N/A

   Table 2: Summary of Attributes

*/
#define STUN_COMMAND_BIND_REQUEST					0X0001
#define STUN_COMMAND_SHARED_SECRET_REQUEST			0X0002
//TURN draft rosenberg-midcom-turn-07
#define TURN_COMMAND_ALLOCATE_REQUEST				0X0003
#define TURN_COMMAND_SEND_REQUEST					0X0004
//use as media service 
#define TURN_COMMAND_ALLOCATE_CHANNEL_REQUEST		0X0010
#define TURN_COMMAND_RELEASE_CHANNEL_REQUEST		0X0011
#define TURN_COMMAND_START_RECORD_REQUEST			0X0012
#define TURN_COMMAND_STOP_RECORD_REQUEST			0X0013
#define TURN_COMMAND_ALLOCATE_RELAY_REQUEST			0x0014


#define STUN_COMMAND_BIND_RESPONSE					0X0101
#define STUN_COMMAND_BIND_ERROR_RESPONSE			0X0111
#define STUN_COMMAND_SHARED_SECRET_RESPONSE			0X0102
#define STUN_COMMAND_SHARED_SECRET_ERROR_RESPONSE	0X0112
//TURN draft rosenberg-midcom-turn-07
#define TURN_COMMAND_ALLOCATE_RESPONSE				0X0103
#define TURN_COMMAND_ALLOCATE_ERROR_RESPONSE		0X0113
#define TURN_COMMAND_SEND_RESPONSE					0X0104
#define TURN_COMMAND_SEND_ERROR_RESPONSE			0X0114
#define TURN_COMMAND_DATA_INDICATION				0X0115
#define TURN_COMMAND_ALLOCATE_RELAY_RESPONSE		0X0116
#define TURN_COMMAND_ALLOCATE_RELAY_ERROR_RESPONSE	0X0117

#define TURN_COMMAND_ALLOCATE_CHANNEL_RESPONSE			0X0200
#define TURN_COMMAND_ALLOCATE_CHANNEL_ERROR_RESPONSE	0X0201
#define TURN_COMMAND_RELEASE_CHANNEL_RESPONSE			0X0202
#define TURN_COMMAND_RELEASE_CHANNEL_ERROR_RESPONSE		0X0203
#define TURN_COMMAND_START_RECORD_RESPONSE				0X0204
#define TURN_COMMAND_START_RECORD_ERROR_RESPONSE		0X0205
#define TURN_COMMAND_STOP_RECORD_RESPONSE				0X0206
#define TURN_COMMAND_STOP_RECORD_ERROR_RESPONSE			0X0207


//for media server
#define MS_COMMAND_ALLOCATE_CHANNEL_REQUEST			0X0300
#define MS_COMMAND_ALLOCATE_CHANNEL_RESPONSE		0X0301
#define MS_COMMAND_ALLOCATE_CHANNEL_ERROR_RESPONSE	0X0302
#define MS_COMMAND_ALLOCATE_RECV_CHANNEL_REQUEST	0X0303
#define MS_COMMAND_ALLOCATE_RELAY_CHANNEL_REQUEST	0X0304
#define MS_COMMAND_RELEASE_RECV_CHANNEL_REQUEST		0X0305
#define MS_COMMAND_RELEASE_RELAY_CHANNEL_REQUEST	0X0306

#define MS_COMMAND_RELEASE_CHANNEL_REQUEST			0X0380
#define MS_COMMAND_RELEASE_CHANNEL_RESPONSE			0X0381
#define MS_COMMAND_RELEASE_CHANNEL_ERROR_RESPONSE	0X0382
#define MS_COMMAND_ALLOCATE_RECV_CHANNEL_RESPONSE	0X0383
#define MS_COMMAND_ALLOCATE_RELAY_CHANNEL_RESPONSE	0X0384
#define MS_COMMAND_RELEASE_RECV_CHANNEL_RESPONSE	0X0385
#define MS_COMMAND_RELEASE_RELAY_CHANNEL_RESPONSE	0X0386
#define MS_COMMAND_ALLOCATE_RECV_CHANNEL_ERROR_RESPONSE	0X0387
#define MS_COMMAND_ALLOCATE_RELAY_CHANNEL_ERROR_RESPONSE	0X0388


struct STUN_MESSAGE_HEADER{
	unsigned short	command;
	unsigned short	length;
	unsigned char	transactionid[16];
};
class CTurnMessage  
{
public:
	static void GeneralID(char *pid);
	CTurnMessage();
	virtual ~CTurnMessage();
	bool Parse(const char *pdata,int len);
	void Clear();
	int Encode(char *pdata,int len);
	const unsigned char *GetTransactionID(){return m_TransactionID;};
	void SetTransactionID(const char *ptid){memcpy(m_TransactionID,ptid,16);};
	int GetCommand(){return m_nCommand;};
	void SetCommand(int command){m_nCommand = command;};
	void AddMappedAddress(CMappedAddress *pmap);	
	void AddResponseAddress(CResponseAddress *pr);
	void AddChangeRequest(CChangeRequest *pc);
	void AddSourceAddress(CSourceAddress *ps);
	void AddChangedAddress(CChangedAddress *pc);
	void AddUserName(CUserName *pu);
	void AddPassword(CPassword *pp);
	void AddChannelID(CChannelID *pchid);	
	void AddErrorCode(CErrorCode *pec);
	void AddUnknownAttributes(CUnknownAttributes *pu);
	void AddReflectedFrom(CReflectedFrom *pr);
	void AddNonce(CNonce *pnoce);
	void AddLifeTime(CLifeTime *plt);
	void AddStartTime(CStartTime *pst);
	void AddStopTime(CStopTime *pst);
	void AddMagicCookie(CMagicCookie*pmc);
	void AddAlternateServer(CAlternateServer*	pas);
	void AddBandwidth(CBandwidth* pbw);
	void AddDestinationAddress(CDestinationAddress*	pda);
	void AddRealm(CRealm *prealm);
	void AddMessageIntegrity(CMessageIntegrity *pi);
	void AddData(CData *pdata);
	void AddRecordID(CRecordID*	pRecordID);
	void AddOwnerID(COwnerID *pOwnerID);
	void AddVideoFormat(CVideoformat*	pVideoFormat);
	void AddVideoFrameRate(CVideoframerate*	pVideoFrameRate);
	void AddVideoHeight(CVideoheight*	pVideoHeight);
	void AddVideoWidth(CVideowidth*	pVideoWidth);
	void AddSubTitle(CSubTitle *pSubTitle);
	void AddSubTitlePos(CSubTitlePos *pSubTitlePos);
	void AddTimeTitlePos(CTimeTitlePos *pTimeTitlePos);
	void AddRecvChannel(CRecvChannel *pchid);
	void AddRelayChannel(CRelayChannel *prid);
	void AddRelayServerID(CRelayServerID *pid);
	
	void AddPlayScale(CPlayScale* pScale);
	void AddPlayType(CPlayType* pType);

	const CMappedAddress* GetMappedAddress(){return	m_pMappedAddress; };
    const CResponseAddress*	GetResponseAddress(){return m_pResponseAddress; };
    const CChangeRequest* GetChangeRequest(){return m_pChangeRequest;};
    const CSourceAddress* GetSourceAddress(){return m_pSourceAddress;};
    const CChangedAddress*	GetChangedAddress(){return m_pChangedAddress;};
    const CUserName* GetUserName(){return m_pUserName;};
    const CPassword* GetPassword(){return m_pPassword;};
    const CChannelID* GetChannelID(){return m_pChannelID;};
    const CErrorCode* GetErrorCode(){return m_pErrorCode;};
    const CUnknownAttributes* GetUnknownAttributes(){return m_pUnknownAttributes;};
    const CReflectedFrom* GetReflectedFrom(){return m_pReflectedFrom;};
	const CNonce* GetNonce(){return m_pNonce;};
	const CLifeTime* GetLifeTime(){return m_pLifeTime;};
	const CStartTime* GetStartTime(){return m_pStartTime;};
	const CStopTime* GetStopTime(){return m_pStopTime;};

	const CMagicCookie* GetMagicCookie(){return m_pMagicCookie;};
	const CAlternateServer* GetAlternateServer(){return m_pAlternateServer;};
	const CBandwidth* GetBandwidth(){return m_pBandwidth;};
	const CDestinationAddress* GetDestinationAddress(){return m_pDestinationAddress;};
	const CRealm* GetRealm(){return m_pRealm;};
	const CMessageIntegrity* GetMessageIntegrity(){return m_pMessageIntegrity;};	
	const CData *GetDATA(){return m_pDATA;};
	const CRecordID* GetRecordID(){return m_pRecordID;};
	const COwnerID *GetOwnerID(){return m_pOwnerID;};
	const CVideoformat*	GetVideoFormat(){return m_pVideoFormat;};
	const CVideoframerate* GetVideoFrameRate(){return m_pVideoFrameRate;};
	const CVideoheight*	GetVideoHeight(){return m_pVideoHeight;};
	const CVideowidth*	GetVideoWidth(){return m_pVideoWidth;};
	const CSubTitle* GetSubTitle(){return m_pSubTitle;};
	const CSubTitlePos* GetSubTitlePos(){return m_pSubTitlePos;};
	const CTimeTitlePos* GetTimeTitlePos(){return m_pTimeTitlePos;};
	const CRecvChannel*	GetRecvChannel(){return m_pRecvChannel;};
	const CRelayChannel* GetRelayChannel(){return m_pRelayChannel;};
	const CRelayServerID* GetRelayServerID(){return	m_pRelayServerID;};

	const CPlayScale*	GetPlayScale() { return m_pPlayScale; };
	const CPlayType*	GetPlayType() { return m_pPlayType; };

	int GetLength(){return m_nLength + 20;};
	const char *GetData()const{return m_pData;};
	int GetDataLength()const{return m_nDataLength;};
protected:
	CMappedAddress*		m_pMappedAddress;    
    CResponseAddress*	m_pResponseAddress;   
    CChangeRequest*		m_pChangeRequest;
    CSourceAddress*		m_pSourceAddress;	
    CChangedAddress*	m_pChangedAddress;	
    CUserName*			m_pUserName;      
    CPassword*			m_pPassword;
    CMessageIntegrity*	m_pMessageIntegrity;
    CErrorCode*			m_pErrorCode;
    CUnknownAttributes*	m_pUnknownAttributes;	
    CReflectedFrom*		m_pReflectedFrom;	
	CNonce*				m_pNonce;
	CRealm*				m_pRealm;
	CLifeTime*			m_pLifeTime;
	CStartTime*			m_pStartTime;
	CStopTime*			m_pStopTime;
	CMagicCookie*		m_pMagicCookie;
	CAlternateServer*	m_pAlternateServer;
	CBandwidth*			m_pBandwidth;
	CDestinationAddress*m_pDestinationAddress;
	CChannelID*			m_pChannelID;
	CData*				m_pDATA;
	CRecordID*			m_pRecordID;
	COwnerID*			m_pOwnerID;
	CVideoformat*		m_pVideoFormat;
	CVideoframerate*	m_pVideoFrameRate;
	CVideoheight*		m_pVideoHeight;
	CVideowidth*		m_pVideoWidth;

	
	CSubTitle*			m_pSubTitle;
	CSubTitlePos*		m_pSubTitlePos;
	CTimeTitlePos*		m_pTimeTitlePos;
	CRecvChannel*		m_pRecvChannel;
	CRelayChannel*		m_pRelayChannel;
	CRelayServerID*		m_pRelayServerID;
    //StunAtrAddress4  xorMappedAddress;      
    //StunAtrString serverName;      
    //StunAtrAddress4 secondaryAddress;

	CPlayScale*			m_pPlayScale;
	CPlayType*			m_pPlayType;
	
#ifdef _EHOME_
protected:
	
	// Stone Whoo add the following virtual functions @20070131
	// If any extension to TURN, the child class should implement the following virutal functions
	virtual int ParsePlugin(const char* pdata, int len)	{return 0;};
	virtual void ClearPlugin()	{};
	virtual int	EncodePlugin(char* pdata, int len){return 0;}
	// Stone Whoo end add @20070131
#endif
protected:
	int				m_nCommand;
	int				m_nLength;
	unsigned char	m_TransactionID[16];
	char*			m_pData;
	int				m_nDataLength;
};

#endif // !defined(AFX_STUNPROTOCOL_H__70690076_F20A_4DA5_B0E5_FB14D1F22751__INCLUDED_)
